import hashlib
import datetime
import base64


class MsgDigest:
    def get_digest(self, **kwargs):
        """
        获取摘要
        """
        app_id = kwargs.get("app_id")
        timestamp = kwargs.get("timestamp")
        app_secret = kwargs.get("app_secret")
        payload: dict = kwargs.get("payload")
        # 1。将参与摘要计算的业务参数按字典升序排列
        payload_keys = payload.keys()
        sort_payload_keys = sorted(payload_keys)
        params_str = app_secret
        for key_name in sort_payload_keys:
            params_str += str(payload[key_name])
        # 2.对得到的字符串进⾏SHA1 加密
        sh = hashlib.sha1()
        # sh.update((APP_SECRET + cert_flag + customer_id + page_modify + verified_way).encode('utf-8'))
        sh.update(params_str.encode("utf-8"))
        # 3.计算 timestamp的MD5值，并和app_id，步骤 2 中得到的字符串拼接得到新的字符串
        md = hashlib.md5()
        md.update(timestamp.encode("utf-8"))
        sha1 = app_id.encode("utf-8") + str(md.hexdigest().upper()).encode(
            "utf-8") + sh.hexdigest().upper().encode("utf-8")
        # 4.对步骤3中得到的字符串进行SHA1 加密
        sh = hashlib.sha1()
        sh.update(sha1)
        # 5.对步骤 4 中得到的字符串进⾏base64 加密
        Msg_digest = base64.b64encode(sh.hexdigest().upper().encode("utf-8")).decode()
        return Msg_digest

    def get_digest_file(self, **kwargs):
        """
        上传合同模板文件时的签名
        """
        app_id = kwargs.get("app_id")
        timestamp = kwargs.get("timestamp")
        app_secret = kwargs.get("app_secret")
        template_id = kwargs.get("template_id")
        # 1。将参与摘要计算的业务参数按字典升序排列
        params_str = app_secret + template_id
        # 2.对得到的字符串进⾏SHA1 加密
        sh = hashlib.sha1()
        # sh.update((APP_SECRET + cert_flag + customer_id + page_modify + verified_way).encode('utf-8'))
        sh.update(params_str.encode("utf-8"))
        # 3.计算 timestamp的MD5值，并和app_id，步骤 2 中得到的字符串拼接得到新的字符串
        md = hashlib.md5()
        md.update(timestamp.encode("utf-8"))
        sha1 = app_id.encode("utf-8") + str(md.hexdigest().upper()).encode(
            "utf-8") + sh.hexdigest().upper().encode("utf-8")
        # 4.对步骤3中得到的字符串进行SHA1 加密
        sh = hashlib.sha1()
        sh.update(sha1)
        # 5.对步骤 4 中得到的字符串进⾏base64 加密
        Msg_digest = base64.b64encode(sh.hexdigest().upper().encode("utf-8")).decode()
        return Msg_digest

    def generate_contract_digest(self, **kwargs):
        """
        模板填充 签名
        """
        app_id = kwargs.get("app_id")
        timestamp = kwargs.get("timestamp")
        app_secret = kwargs.get("app_secret")
        template_id = kwargs.get("template_id")
        contract_id = kwargs.get("contract_id")
        parameter_map = kwargs.get("parameter_map")
        # 1。将参与摘要计算的业务参数按字典升序排列
        params_str = app_secret + template_id + contract_id
        # 2.对得到的字符串进⾏SHA1 加密
        sh = hashlib.sha1()
        sh.update(params_str.encode("utf-8"))
        # 3.计算 timestamp的MD5值，并和app_id，步骤 2 中得到的字符串拼接得到新的字符串
        md = hashlib.md5()
        md.update(timestamp.encode("utf-8"))
        sha1 = app_id.encode("utf-8") + str(md.hexdigest().upper()).encode(
            "utf-8") + sh.hexdigest().upper().encode("utf-8") + parameter_map.encode("utf-8")
        # 4.对步骤3中得到的字符串进行SHA1 加密
        sh = hashlib.sha1()
        sh.update(sha1)
        # 5.对步骤 4 中得到的字符串进⾏base64 加密
        Msg_digest = base64.b64encode(sh.hexdigest().upper().encode("utf-8")).decode()
        return Msg_digest

    def uploaddocs_digest(self, **kwargs):
        """
        上传合同 签名
        """
        app_id = kwargs.get("app_id")
        timestamp = kwargs.get("timestamp")
        app_secret = kwargs.get("app_secret")
        contract_id = kwargs.get("contract_id")
        # 1。将参与摘要计算的业务参数按字典升序排列
        params_str = app_secret + contract_id
        # 2.对得到的字符串进⾏SHA1 加密
        sh = hashlib.sha1()
        sh.update(params_str.encode("utf-8"))
        # 3.计算 timestamp的MD5值，并和app_id，步骤 2 中得到的字符串拼接得到新的字符串
        md = hashlib.md5()
        md.update(timestamp.encode("utf-8"))
        sha1 = app_id.encode("utf-8") + str(md.hexdigest().upper()).encode(
            "utf-8") + sh.hexdigest().upper().encode("utf-8")
        # 4.对步骤3中得到的字符串进行SHA1 加密
        sh = hashlib.sha1()
        sh.update(sha1)
        # 5.对步骤 4 中得到的字符串进⾏base64 加密
        Msg_digest = base64.b64encode(sh.hexdigest().upper().encode("utf-8")).decode()
        return Msg_digest

    def extsign_digest(self, **kwargs):
        """
        手动签署 签名
        """
        app_id = kwargs.get("app_id")
        timestamp = kwargs.get("timestamp")
        app_secret = kwargs.get("app_secret")
        customer_id = kwargs.get("customer_id")
        transaction_id = kwargs.get("transaction_id")
        # 1。将参与摘要计算的业务参数按字典升序排列
        params_str = app_secret + customer_id
        # 2.对得到的字符串进⾏SHA1 加密
        sh = hashlib.sha1()
        sh.update(params_str.encode("utf-8"))
        # 3.计算 timestamp的MD5值，并和app_id，步骤 2 中得到的字符串拼接得到新的字符串
        md = hashlib.md5()
        md.update((transaction_id + timestamp).encode("utf-8"))
        sha1 = app_id.encode("utf-8") + str(md.hexdigest().upper()).encode(
            "utf-8") + sh.hexdigest().upper().encode("utf-8")
        # 4.对步骤3中得到的字符串进行SHA1 加密
        sh = hashlib.sha1()
        sh.update(sha1)
        # 5.对步骤 4 中得到的字符串进⾏base64 加密
        Msg_digest = base64.b64encode(sh.hexdigest().upper().encode("utf-8")).decode()
        return Msg_digest


if __name__ == '__main__':
    now = datetime.datetime.now()
    timestamp_str = now.strftime("%Y%m%d%H%M%S")
    payload = {
        "account_type": 1,
        "open_id": "testopenid"
    }
    params = {
        "payload": payload,
        "app_id": "406595",
        "timestamp": timestamp_str,
        "v": "2.0",
        "app_secret": "lpeFgRmpkuH7JhbSqsGMWqkb"
    }
    result = MsgDigest().get_digest(**params)
    print(result)
